package cn.t.converter.user;

import cn.t.model.user.ResourceInfoDO;
import cn.t.vo.user.ResourceTreeVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author l
 */
@Slf4j
@Component
public class ResourceTreeConverter {

    public List<ResourceTreeVO> convert(Set<Long> resourceIdSet, Map<Long, ResourceInfoDO> resourceMap) {
        Map<Long, ResourceTreeVO> tmp = doToVo(resourceMap);

        // 设置默认的访问权限
        for (Long resourceId : resourceIdSet) {
            if (!resourceMap.containsKey(resourceId)) {
                continue;
            }
            tmp.get(resourceId).setHasRights(true);
        }

        // 补全上级菜单的访问权限
        for (Map.Entry<Long, ResourceTreeVO> entry : tmp.entrySet()) {
            if (entry.getValue().getHasRights() && (entry.getValue().getChildren() == null || entry.getValue().getChildren().isEmpty())) {
                setParentRights(entry.getValue().getParentId(), tmp);
            }
        }

        List<ResourceTreeVO> ret = new ArrayList<>();
        for (ResourceTreeVO root : tmp.values()) {
            if (root.getParentId() == 0) {
                ret.add(root);
            }
        }
        return ret;
    }

    private void setParentRights(Long parentId, Map<Long, ResourceTreeVO> tmp) {
        if (parentId == null || parentId <= 0 || tmp == null || !tmp.containsKey(parentId)) {
            return;
        }

        tmp.get(parentId).setHasRights(true);
        ResourceTreeVO current = tmp.get(parentId);

        if (current.getParentId() != null && current.getParentId() > 0
                && !current.getResourceId().equals(current.getParentId())) {
            setParentRights(tmp.get(parentId).getParentId(), tmp);
        }
    }

    public List<ResourceTreeVO> convert(Map<Long, ResourceInfoDO> resourceInfoMap) {

        List<ResourceTreeVO> ret = new ArrayList<>();
        Map<Long, ResourceTreeVO> tmp = doToVo(resourceInfoMap);
        for (ResourceTreeVO root : tmp.values()) {
            if (root.getParentId() == 0) {
                ret.add(root);
            }
        }
        return ret;
    }

    public Map<Long, ResourceTreeVO> doToVo(Map<Long, ResourceInfoDO> resourceMap) {
        Map<Long, ResourceTreeVO> tmp = new HashMap<>();

        for (Map.Entry<Long, ResourceInfoDO> entry : resourceMap.entrySet()) {
            ResourceInfoDO resourceInfo = entry.getValue();

            ResourceTreeVO leaf = convert(resourceInfo);

            if (resourceInfo.getParentId() == null || resourceInfo.getParentId() == 0) {
                leaf.setParentId(0L);
                leaf.setLevel(0);
            } else {
                if (tmp.containsKey(resourceInfo.getParentId())) {
                    ResourceTreeVO parent = tmp.get(resourceInfo.getParentId());
                    if (parent.getLevel() != null) {
                        leaf.setLevel(parent.getLevel() + 1);
                    }
                    tmp.get(parent.getResourceId()).getChildren().add(leaf);
                }
            }
            tmp.put(leaf.getResourceId(), leaf);
        }

        return tmp;

    }


    public ResourceTreeVO convert(ResourceInfoDO resourceInfoDO) {
        ResourceTreeVO resourceTreeVO = new ResourceTreeVO();
        resourceTreeVO.setResourceId(resourceInfoDO.getId());
        resourceTreeVO.setResourceName(resourceInfoDO.getResourceName());
        resourceTreeVO.setResourceCode(resourceInfoDO.getResourceCode());
        resourceTreeVO.setResourceType(resourceInfoDO.getResourceType());
        resourceTreeVO.setResourceUrl(resourceInfoDO.getResourceUrl());
        resourceTreeVO.setIconUrl(resourceInfoDO.getIconUrl());
        resourceTreeVO.setSort(resourceInfoDO.getSort());
        resourceTreeVO.setRemark(resourceInfoDO.getRemark());
        resourceTreeVO.setParentId(resourceInfoDO.getParentId());
        resourceTreeVO.setIsHidden(resourceInfoDO.getIsHidden());
        resourceTreeVO.setScenarioId(resourceInfoDO.getScenarioId());
        resourceTreeVO.setChildren(new ArrayList<>());
        return resourceTreeVO;

    }


}
